package com.wheel.autoconfigure.drools;/*
 * <h3>Title:wheel-parent系统</h3>
 * <p>Copyright (c) 2021, wnfbx. All rights reserved.</p>
 * @author wnfbx
 */

import com.wheel.core.utils.Log;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieScanner;
import org.kie.api.definition.KiePackage;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.utils.KieHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.ResourceUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * <dt>Description:DroolsUtils</dt>
 * <dd>Drools工具类</dd>
 *
 * @author wnfbx
 * @version 1.0 <i>2021/8/7 11:43</i>
 * @since jdk1.7+
 */
public class DroolsUtils {

    private static final Logger log = LoggerFactory.getLogger(DroolsUtils.class);

    public static KieContainer newKieContainer(KieServices kieServices, KieModule kieModule) {
        return kieServices.newKieContainer(kieModule.getReleaseId());
    }

    public static KieModule newKieModule(KieServices kieServices, KieFileSystem kieFileSystem) {
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
        kieBuilder.buildAll();
        return kieBuilder.getKieModule();
    }

    public static KieFileSystem kieFileSystem(KieServices kieServices, List<String> locationPatterns) throws IOException {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        for (String locationPattern : locationPatterns) {
            Resource[] resources = resourcePatternResolver.getResources(locationPattern);
            Log.debug(log, "配置规则文件路径：{}", locationPattern);
            for (Resource resource : resources) {
                org.kie.api.io.Resource kieResource;
                String path = resource.getURL().getPath();
                if (ResourceUtils.isJarURL(resource.getURL())) {
                    String fileClassPath = path.substring(path.indexOf("classes!") + 8);
                    Log.debug(log, "读取jar包内规则文件：{},{}", path, fileClassPath);
                    kieResource = kieServices.getResources().newClassPathResource(fileClassPath, "utf-8");
                } else {
                    Log.debug(log, "读取jar包外规则文件：{}", path);
                    kieResource = kieServices.getResources().newFileSystemResource(path, "utf-8");
                }
                kieFileSystem.write(kieResource);
            }
        }
        return kieFileSystem;
    }

    //必须依赖drools-compiler 这个包有KieServices实现类
    public static KieServices getKieServices() {
        return KieServices.get();
    }

    //必须依赖kie-ci 这个包有KieScanner实现类
    public static void createKieScannerAndStart(KieServices kieServices, KieContainer kieContainer, long scannerInterval) {
        if (scannerInterval > 0) {
            Log.debug(log, "配置自动扫描频率：{}", scannerInterval);
            KieScanner kieScanner = kieServices.newKieScanner(kieContainer);
            kieScanner.start(scannerInterval);
        }
    }

    public static KieSession newKieSessionByService(String... locationPatterns) throws IOException {
        KieServices kieServices = getKieServices();
        return DroolsUtils.newKieContainer(kieServices, DroolsUtils.newKieModule(kieServices, DroolsUtils.kieFileSystem(kieServices, Arrays.asList(locationPatterns)))).newKieSession();
    }

    public static KieSession newKieSessionByHelper(String... locationPatterns) throws IOException {
        KieHelper kieHelper = new KieHelper();
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        for (String locationPattern : locationPatterns) {
            Resource[] resources = resourcePatternResolver.getResources(locationPattern);
            Log.debug(log, "配置规则文件路径：{}", locationPattern);
            for (Resource resource : resources) {
                org.kie.api.io.Resource kieResource;
                String path = resource.getURL().getPath();
                if (ResourceUtils.isJarURL(resource.getURL())) {
                    String fileClassPath = path.substring(path.indexOf("classes!") + 8, path.length());
                    Log.debug(log, "读取jar包内规则文件：{},{}", path, fileClassPath);
                    kieResource = ResourceFactory.newClassPathResource(fileClassPath, "utf-8");
                } else {
                    Log.debug(log, "读取jar包外规则文件：{}", path);
                    kieResource = ResourceFactory.newUrlResource(resource.getURL());
                }
                kieHelper.addResource(kieResource);
            }
        }
        KieBase kieBase = kieHelper.build();
        validateConfig(kieBase);
        return kieHelper.build().newKieSession();
    }

    public static void validateConfig(KieBase kb) throws IOException {
        Collection<KiePackage> kiePackages = kb.getKiePackages();
        int total = 0;
        StringBuilder pkg = new StringBuilder();
        for (KiePackage kiePackage : kiePackages) {
            int size = kiePackage.getRules().size();
            total += size;
            Log.info(log, "共有规则{}个，package:{}", size, kiePackage.getName());
            if (total == 0) {
                pkg.append(",").append(kiePackage.getName());
            }
        }
        if (total == 0) {
            throw new IOException(Log.formatMessage("{}下,没有时间匹配规则", pkg.substring(1)));
        }
    }

}
